#pragma once
#include <string>
#include "util.hpp"
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>

using namespace std;

const string set = "\r\n";
const string home_page = "index.html";	   // 首页
const string root_directory = "./wwwroot"; // 根目录
const string html_404 = "./wwwroot/404.html";


// 请求
class HttpRequest
{
public:
	HttpRequest()
	{
	}

	// 将请求的第一行的方法，路径，版本分别放入该字符串中
	// 将客户端的访问路径放入path，将要访问的网络文件的字节数放入size
	void parse()
	{
		// 得到请求的第一行
		string line = Util::getfirstline(inbuffer, set);
		if (line.size() == 0)
			return; // 没有获取到一行信息，出错

		// 使用这一行信息构造一个stringstream变量
		std::stringstream ss(line);
		// 从该变量中以空格为分隔符分别将信息放入变量中
		ss >> method >> url >> httpversion;

		// 添加路径
		path += root_directory; // 先设置网络根目录./wwwroot
		path += url;			// url:表示根目录之后的路径，再将url追加在根目录之后，例如：./wwwroot/text/a.html

		// 如果path最后1一个是'/'，则表示客户端访问的是该网站的首页
		if (path[path.size() - 1] == '/')
		{
			path += home_page; // 将首页追加到path中: ./wwwwroot/index.html
		}


		//获取path对应的资源后缀
		//例：./wwwroot/index.html
		//./wwwroot/text/a.html
		//./wwwroot/image/1.png
		auto pos=path.find(".");//从后往前找
		if(pos==string::npos)
		{
			suffix=".html";//找不到，默认它的后缀为html
		}
		else
		{
			suffix=path.substr(pos);//找到了，从.开始截取字符，存入suffix中
		}
		

		// 网络文件的大小
		struct stat st;
		int n = stat(path.c_str(), &st);
		if (n == 0) // 如果返回值为0，则资源获取成功，将该网络文件的字节数赋给size
		{
			size = st.st_size;
		}
		else // 如果资源获取失败，则设置404.html，并将其字节数赋给size
		{
			n = stat(html_404.c_str(), &st);
			size = st.st_size;
		}
	}

	

public:
	string inbuffer;	// 完整请求
	string method;		// 请求方法
	string url;			// 请求url
	string httpversion; // 请求版本
	string path;		// 请求路径
	string suffix;      //文件后缀
	int size;			// 网络文件的大小
};

// 回应
class HttpResponse
{
public:
	HttpResponse()
	{
	}

public:
	string outbuffer;
};